﻿using System;
using System.Collections.Generic;
using System.Web;

namespace LOTRO_DPS_Parser
{
    public class ParseCombatLog
    {
        public int ParseDPS(string t1, string t2, List<string> file)
        {
            int totalDPS = 0;

            foreach (string l in file)
            {
                bool bDPS = l.Contains(" for ");
                bool bGamble = l.Contains("(");
                bool bTier = l.Contains("Tier ");
                bool bKeep;
                if (l.Contains(" Grimwood") || l.Contains("Tirith Rhaw") || l.Contains(" Tol ") || l.Contains(" Isendeep ") ||
                    l.Contains(" Lugazag") || l.Contains(" outpost ") || l.Contains(" Outpost "))
                {
                    bKeep = true;
                }
                else
                {
                    bKeep = false;
                }

                // If "All" was selected, get all the outgoing DPS regardless of target
                if (t2 == "All")
                {
                    if (bDPS == true && bKeep == false)
                    {
                        if (l.StartsWith(t1) == true)
                        {
                            if (bGamble == true)
                            {
                                string[] line = l.Split(')');

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else if (bTier == true)
                            {
                                string[] delimiter = new string[] { " on " };
                                string[] line = l.Split(delimiter, StringSplitOptions.None);

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else
                            {
                                string n = l.Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                        }
                    }
                }

                // If "All" was selected, get all the incoming DPS regardless of source
                else if (t1 == "All")
                {
                    if (bDPS == true && bKeep == false)
                    {
                        if (l.StartsWith(t2) == false)
                        {
                            if (bGamble == true)
                            {
                                string[] line = l.Split(')');

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else if (bTier == true)
                            {
                                string[] delimiter = new string[] { " on " };
                                string[] line = l.Split(delimiter, StringSplitOptions.None);

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else
                            {
                                string n = l.Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                        }
                    }
                }

                // If a specific opponent was selected, only get DPS to and from that target
                else
                {
                    if (bDPS == true && bKeep == false)
                    {
                        if (l.StartsWith(t1) == true && l.Contains(t2))
                        {

                            if (bGamble == true)
                            {
                                string[] line = l.Split(')');

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else if (bTier == true)
                            {
                                string[] delimiter = new string[] { " on " };
                                string[] line = l.Split(delimiter, StringSplitOptions.None);

                                string n = line[1].Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                            else
                            {
                                string n = l.Replace(",", "");
                                string number = ExtractNumbers(n);
                                int numVal = Convert.ToInt32(number);
                                totalDPS = totalDPS + numVal;
                            }
                        }
                    }
                }
            }
            return totalDPS;
        }

        public string[] FindBiggestHit(string t1, string t2, List<string> file)
        {

            List<string> hitData = new List<string>();
            int bigHit = 0;
            string bigLog = "";
            string strBigHit = "";
            foreach (string l in file)
            {
                bool bDPS = l.Contains(" for ");
                bool bGamble = l.Contains("(");
                bool bTier = l.Contains("Tier ");
                bool bKeep;
                if (l.Contains(" Grimwood") || l.Contains("Tirith Rhaw") || l.Contains(" Tol ") || l.Contains(" Isendeep ") ||
                    l.Contains(" Lugazag") || l.Contains(" outpost") || l.Contains(" Outpost"))
                {
                    bKeep = true;
                }
                else
                {
                    bKeep = false;
                }
                // If "All" was selected, get the biggest single outgoing hit against any target
                if (t2 == "All")
                {
                    if (bDPS == true && bGamble == false && bTier == false && bKeep == false)
                    {
                        if (l.StartsWith(t1) == true)
                        {
                            string n = l.Replace(",", "");
                            string number = ExtractNumbers(n);
                            int numVal = Convert.ToInt32(number);
                            if (numVal > bigHit)
                            {
                                bigHit = numVal;
                                strBigHit = number;
                                bigLog = l.ToString();
                            }

                        }
                    }
                }

                // If "All" was selected, find the biggest single incoming hit from any source
                else if (t1 == "All")
                {
                    if (bDPS == true && bGamble == false && bTier == false && bKeep == false)
                    {
                        if (l.StartsWith(t2) == false)
                        {
                            string n = l.Replace(",", "");
                            string number = ExtractNumbers(n);
                            int numVal = Convert.ToInt32(number);
                            if (numVal > bigHit)
                            {
                                bigHit = numVal;
                                strBigHit = number;
                                bigLog = l.ToString();

                            }
                        }
                    }
                }

                // If a specific opponent was selected, only find the biggest hit between the two targets
                else
                {
                    if (bDPS == true && bGamble == false && bTier == false && bKeep == false)
                    {
                        if (l.StartsWith(t1) == true && l.Contains(t2))
                        {
                            string n = l.Replace(",", "");
                            string number = ExtractNumbers(n);
                            int numVal = Convert.ToInt32(number);
                            if (numVal > bigHit)
                            {
                                bigHit = numVal;
                                strBigHit = number;
                                bigLog = l.ToString();
                            }
                        }
                    }
                }
            }

            hitData.Add(strBigHit);
            hitData.Add(bigLog);

            string[] data = hitData.ToArray();

            return data;
        }

        // Get total evade events that selected character had
        public int ParseEvades(string t1, string t2, List<string> file)
        {
            int evades = 0;

            foreach (string l in file)
            {
                bool bTried = l.Contains(" tried ");

                if (t1 == "All")
                {

                    if (l.StartsWith(t2) == false && l.Contains(" evaded ") == true && l.Contains(" partially ") == false)
                    {
                        evades++;
                    }
                }

                else if (t2 == "All")
                {
                    if (l.StartsWith(t1) == true && l.Contains(" evaded ") == true && l.Contains(" partially ") == false)
                    {
                        evades++;
                    }
                }
                else
                {
                    if (l.StartsWith(t1) == true && l.Contains(" evaded ") == true && l.Contains("partially") == false && l.Contains(t2) == true)
                    {
                        evades++;
                    }
                }
            }
            return evades;
        }

        // Get total block events that selected character had
        public int ParseBlocks(string t1, string t2, List<string> file)
        {
            int blocks = 0;

            foreach (string l in file)
            {
                bool bTried = l.Contains("tried");

                if (t1 == "All")
                {

                    if (l.StartsWith(t2) == false && l.Contains(" blocked ") == true && l.Contains(" partially ") == false)
                    {
                        blocks++;
                    }
                }

                else if (t2 == "All")
                {
                    if (l.StartsWith(t1) == true && l.Contains(" blocked ") == true && l.Contains(" partially ") == false)
                    {
                        blocks++;
                    }
                }

                else
                {
                    if (l.StartsWith(t1) == true && l.Contains(" blocked ") == true && l.Contains(" partially ") == false && l.Contains(t2) == true)
                    {
                        blocks++;
                    }
                }
            }

            return blocks;
        }

        // Get total parries that selected character had
        public int ParseParries(string t1, string t2, List<string> file)
        {
            int parries = 0;

            foreach (string l in file)
            {
                bool bTried = l.Contains(" tried ");

                if (t1 == "All")
                {
                    if (l.StartsWith(t2) == false && l.Contains(" parried ") == true && l.Contains(" partially ") == false)
                    {
                        parries++;
                    }
                }

                else if (t2 == "All")
                {
                    if (l.StartsWith(t1) == true && l.Contains(" parried ") == true && l.Contains(" partially ") == false)
                    {
                        parries++;
                    }
                }

                else
                {
                    if (l.StartsWith(t1) == true && l.Contains(" parried ") == true && l.Contains(" partially ") == false && l.Contains(t2) == true)
                    {
                        parries++;
                    }
                }
            }
            return parries;
        }

        public decimal DamagePerAttack(int a, int d)
        {

            decimal p = (decimal)d / (decimal)a;
            decimal rounded = decimal.Round(p, 2);
            return rounded;
        }

        public int NumberOfAttacks(string t1, string t2, List<string> file)
        {
            int attacks = 0;

            foreach (string l in file)
            {
                bool bKeep;
                if (l.Contains(" Grimwood") || l.Contains("Tirith Rhaw") || l.Contains(" Tol ") || l.Contains(" Isendeep ") ||
                    l.Contains(" Lugazag") || l.Contains(" outpost") || l.Contains(" Outpost"))
                {
                    bKeep = true;
                }
                else
                {
                    bKeep = false;
                }
                if (t1 == "All")
                {
                    if (l.StartsWith(t2) == false && bKeep == false && (l.Contains(" for ") || l.Contains(" tried ") == true))
                    {
                        attacks++;
                    }
                }

                else if (t2 == "All")
                {
                    if (l.StartsWith(t1) == true && bKeep == false && (l.Contains(" for ") || l.Contains(" tried ") == true))
                    {
                        attacks++;
                    }
                }

                else
                {
                    if (l.StartsWith(t1) == true && bKeep == false && l.Contains(t2) && (l.Contains(" for ") || l.Contains(" tried ") == true))
                    {
                        attacks++;
                    }
                }
            }

            return attacks;
        }

        public int PartialAttacks(string str, List<string> file)
        {
            int attacks = 0;

            foreach (string l in file)
            {
                if (l.Contains(str) == true && l.Contains(" partially ") == true)
                {
                    attacks++;
                }
            }

            return attacks;
        }

        public int ParseResists(string t1, string t2, List<string> file)
        {
            int attacks = 0;

            foreach (string l in file)
            {
                bool bTried = l.Contains(" tried ");

                if (t1 == "All")
                {

                    if (l.StartsWith(t2) == false && l.Contains(" resisted ") == true)
                    {
                        attacks++;
                    }
                }

                else if (t2 == "All")
                {
                    if (l.StartsWith(t1) == true && l.Contains(" resisted ") == true)
                    {
                        attacks++;
                    }
                }
                else
                {
                    if (l.StartsWith(t1) == true && l.Contains(" resisted ") == true && l.Contains(t2) == true)
                    {
                        attacks++;
                    }
                }
            }
            return attacks;
        }

        public int MyKillingBlows(List<string> file)
        {
            int kbs = 0;

            foreach (string l in file)
            {
                bool bKB = l.StartsWith("Your mighty blow ");

                if (bKB == true)
                {
                    kbs++;
                }
            }
            return kbs;
        }

        public List<string> WhoDied(List<string> file)
        {
            List<string> names = new List<string>();
            string[] delimiter = new string[] { " " };
            foreach (string l in file)
            {
                bool bKB = l.StartsWith("Your mighty blow ");
                if (bKB == true)
                {
                    string[] words = l.Split(delimiter, StringSplitOptions.None);
                    string name = words[4].Replace(".", "");
                    if (name != "the" && name != "The")
                    {
                        names.Add(name);
                    }
                }
            }

            return names;
        }

        public int FindCrits(string t1, string t2, List<string> file)
        {

            int crits = 0;

            foreach (string l in file)
            {
                if (t1 == "All")
                {
                    if (l.Contains(" applied ") == false && (l.Contains(" critical ") || l.Contains(" devastating ")) && l.StartsWith(t2))
                    {
                        crits++;
                    }
                }
                else if (t2 == "All")
                {
                    if (l.Contains(" applied ") == false && (l.Contains(" critical ") || l.Contains(" devastating ")) && l.StartsWith(t1))
                    {
                        crits++;
                    }
                }
                else
                {
                    if (l.Contains(" applied ") == false && (l.Contains(" critical ") || l.Contains(" devastating ")) && l.StartsWith(t1) && l.Contains(t2))
                    {
                        crits++;
                    }

                }
            }

            return crits;
        }

        public int FindDevCrits(string t1, string t2, List<string> file)
        {

            int devcrits = 0;

            foreach (string l in file)
            {
                if (t1 == "All")
                {
                    if (l.Contains(" applied ") == false && l.Contains(" devastating ") && l.StartsWith(t2))
                    {
                        devcrits++;
                    }
                }
                else if (t2 == "All")
                {
                    if (l.Contains(" applied ") == false && l.Contains(" devastating ") && l.StartsWith(t1))
                    {
                        devcrits++;
                    }
                }
                else
                {
                    if (l.Contains(" applied ") == false && l.Contains(" devastating ") && l.StartsWith(t1) && l.Contains(t2))
                    {
                        devcrits++;
                    }

                }
            }

            return devcrits;
        }

        public int[] GetPoints(List<string> file)
        {
            int totalPoints = 0;
            int totalKills = 0;
            List<int> pointsData = new List<int>();
            int[] arrPoints;
            foreach (string l in file)
            {
                if (l.Contains(" infamy ") || l.Contains(" renown "))
                {
                    string points = ExtractNumbers(l);
                    int numVal = Convert.ToInt32(points);
                    totalPoints = totalPoints + numVal;
                    totalKills++;
                }
            }
            pointsData.Add(totalPoints);
            pointsData.Add(totalKills);
            arrPoints = pointsData.ToArray();
            return arrPoints;

        }

        public decimal CalculatePPK(int a, int b)
        {
            decimal ppk = (decimal)a / (decimal)b;

            ppk = decimal.Round(ppk, 2);

            return ppk;
        }

        public decimal CalculatePercentage(int a, int e)
        {
            int factor = 100;
            decimal percentage = (decimal)e / (decimal)a * (decimal)factor;
            decimal rounded = decimal.Round(percentage, 2);
            return rounded;
        }

        // Extracts numbers from a string
        static string ExtractNumbers(string expr)
        {
            return string.Join(null, System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));
        }
    }
}